"""
耗时任务例子的UI层。
"""
import time
import typing
from decimal import *

from elio import core


def compute_pi(x):
    """
    模拟一个耗时计算任务(计算x位的圆周率）。
    :param x: 计算的精度。
    :return: 圆周率。
    """

    getcontext().prec = x + 1  # 精度控制  +1是因为有3
    pi = Decimal(2)
    i = x * 10  # 迭代次数，根据精度来决定，大概是精度的10倍左右，所以时间复杂度是O(10n)
    while i >= 1:
        # 迭代过程
        pi = pi * Decimal(i) / Decimal(i * 2 + 1) + Decimal(2)
        i -= 1
    r = str(pi)
    return r[:10] + '...' + r[-10:]


class TimeConsumingTaskLayer(core.AutoRecycleLayer[core.Activity]):
    listBox: core.ListLayout = None

    async def on_create(self, *args: typing.Any, **kwargs: typing.Dict):
        await super().on_create(*args, *kwargs)

    async def on_hide(self):
        await super().on_hide()
        if self.listBox:
            await self.listBox.destroy()

    async def on_show(self):
        await super().on_show()
        activity = self.parent
        self.listBox = await core.ListLayout.create(activity)
        btn = await self.listBox.add(core.WidgetButton, .05, widget_args=('运行任务',))
        x = 1000

        async def cb():
            """
            按钮点击事件。
            """
            nonlocal x
            x += 1000
            t = time.time()
            # 我们将计算函数放到进程池中就不会阻塞当前事件循环，可以处理更多的请求
            ret = await core.run_in_process_pool(compute_pi, x)
            t = time.time() - t
            await self.listBox.add(core.WidgetText, 0.1, widget_args=('%d位圆周率%s，耗时%.2f秒' % (x, ret, t),))

        await btn.set_on_click_listener(cb)

    async def on_pause(self):
        await super().on_pause()

    async def on_resume(self):
        await super().on_resume()

    async def on_destroy(self, *args: typing.Any, **kwargs: typing.Dict):
        await super().on_destroy(*args, **kwargs)
